<!DOCTYPE html>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <title>The source code</title>
  <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
  <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
  <style type="text/css">
    .highlight { display: block; background-color: #ddd; }
  </style>
  <script type="text/javascript">
    function highlight() {
      document.getElementById(location.hash.replace(/#/, "")).className = "highlight";
    }
  </script>
</head>
<body onload="prettyPrint(); highlight();">
  <pre class="prettyprint lang-js">var dataUtil = require(&quot;../core/utils/data_structure_util&quot;);

var classUtil = require(&quot;../core/utils/class_util&quot;);

var Track = require(&quot;./Track&quot;);

var Eventful = require(&quot;../event/Eventful&quot;);

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(&quot;Cannot call a class as a function&quot;); } }

function _defineProperties(target, props) { for (var i = 0; i &lt; props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if (&quot;value&quot; in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } }

function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }

<span id='qrenderer-animation-AnimationProcess'>/**
</span> * @class qrenderer.animation.AnimationProcess
 * 
 * AnimationProcess 表示一次完整的动画过程，每一个元素（Element）中都有一个列表，用来存储本实例上的所有动画过程。
 * 列表中的动画过程按照顺序获得运行机会，在特定的时间点上只有一个 AnimationProcess 处于运行状态，运行过程由 GlobalAnimationMgr 进行调度。 
 * AnimationProcess 运行完成之后会触发 done 事件，Element 实例在监听到 done 事件之后，会把对应的动画过程从列表中删除。如果 Element 实例
 * 的动画过程列表中存在多个实例，其中某个过程是无限循环运行的，那么后续所有动画过程都不会获得到运行机会。
 * 
 * @docauthor 大漠穷秋 &lt;damoqiongqiu@126.com&gt;
 */

<span id='qrenderer-animation-AnimationProcess-method-constructor'>/**
</span> * @method constructor AnimationProcess
 * @param {Object} element 需要进行动画的元素
 */
var AnimationProcess =
/*#__PURE__*/
function () {
  function AnimationProcess(element) {
    _classCallCheck(this, AnimationProcess);

    this.element = element;
    this._trackCacheMap = new Map();
    this._delay = 0;
    this._running = false;
    this._paused = false;
    classUtil.inheritProperties(this, Eventful, this.options);
  }
<span id='qrenderer-animation-AnimationProcess-method-when'>  /**
</span>   * @method when
   * 为每一种需要进行动画的属性创建一条轨道
   * @param  {Number} time 关键帧时间，单位ms
   * @param  {Object} config 关键帧的属性值，key-value表示
   * @return {qrenderer.animation.AnimationProcess}
   */


  _createClass(AnimationProcess, [{
    key: &quot;when&quot;,
    value: function when(time, config) {
      var _this = this;

      //TODO:这里需要重构，仿射变换的参数是有顺序的
      var flattenMap = new Map();
      dataUtil.flattenObj(config, flattenMap);
      flattenMap.forEach(function (value, key, map) {
        var track = _this._trackCacheMap.get(key);

        if (!track) {
          track = new Track({
            element: _this.element,
            path: key,
            delay: _this._delay
          }); //如果参数中没有提供第 0 帧，自动补第 0 帧，以元素上当前的属性值为值

          if (time !== 0) {
            var temp = dataUtil.getAttrByPath(_this.element, key);

            if (temp == null || temp == undefined) {
              temp = 0;
            }

            track.addKeyFrame({
              time: 0,
              value: dataUtil.clone(temp)
            });
          }

          _this._trackCacheMap.set(key, track);
        }

        track.addKeyFrame({
          time: time,
          value: dataUtil.clone(value)
        });
      });
      return this;
    }
<span id='qrenderer-animation-AnimationProcess-method-start'>    /**
</span>     * @method start
     * 开始执行动画
     * @param  {Boolean} loop 是否循环
     * @param  {String|Function} [easing] 缓动函数名称，详见{@link qrenderer.animation.easing 缓动引擎}
     * @param  {Boolean} forceAnimate 是否强制开启动画
     * @return {qrenderer.animation.AnimationProcess}
     */

  }, {
    key: &quot;start&quot;,
    value: function start() {
      var loop = arguments.length &gt; 0 &amp;&amp; arguments[0] !== undefined ? arguments[0] : false;
      var easing = arguments.length &gt; 1 &amp;&amp; arguments[1] !== undefined ? arguments[1] : &#39;&#39;;
      var forceAnimate = arguments.length &gt; 2 &amp;&amp; arguments[2] !== undefined ? arguments[2] : false;
      this._running = true;
      this._paused = false;
      this.trigger(&quot;start&quot;);
      var self = this;

      if (!this._trackCacheMap.size) {
        this.trigger(&quot;done&quot;);
        return this;
      }

      this._trackCacheMap.forEach(function (track, key, map) {
        track &amp;&amp; track.start(loop, easing, forceAnimate);
      });

      return this;
    }
<span id='qrenderer-animation-AnimationProcess-method-nextFrame'>    /**
</span>     * @method nextFrame
     * 进入下一帧
     * @param {Number} time  当前时间
     * @param {Number} delta 时间偏移量
     */

  }, {
    key: &quot;nextFrame&quot;,
    value: function nextFrame(time, delta) {
      var _this2 = this;

      this._running = true;
      this._paused = false;
      var deferredEvents = [];
      var deferredTracks = [];
      var percent = &quot;&quot;;
      var isFinished = true;

      this._trackCacheMap.forEach(function (track, key, map) {
        var result = track.nextFrame(time, delta);

        if (dataUtil.isString(result)) {
          deferredEvents.push(result);
          deferredTracks.push(track);
        } else if (dataUtil.isNumeric(result)) {
          percent = result;
        }

        isFinished = isFinished &amp;&amp; track.isFinished;

        if (dataUtil.isNumeric(percent)) {
          _this2.trigger(&quot;during&quot;, _this2.element, track._path, track._currentValue, percent);
        }
      });

      var len = deferredEvents.length;

      for (var i = 0; i &lt; len; i++) {
        deferredTracks[i].fire(deferredEvents[i]);
      }

      if (isFinished) {
        this.trigger(&quot;done&quot;);
      }
    }
<span id='qrenderer-animation-AnimationProcess-method-stop'>    /**
</span>     * @method stop
     * 停止动画
     * @param {Boolean} forwardToLast If move to last frame before stop
     */

  }, {
    key: &quot;stop&quot;,
    value: function stop(forwardToLast) {
      var _this3 = this;

      this._running = false;
      this._paused = false;

      this._trackCacheMap.forEach(function (track, key, map) {
        track.stop(_this3.element, 1);
      });

      this._trackCacheMap = new Map();
      this.trigger(&quot;stop&quot;);
      return this;
    }
<span id='qrenderer-animation-AnimationProcess-method-pause'>    /**
</span>     * @method pause
     * 暂停动画
     */

  }, {
    key: &quot;pause&quot;,
    value: function pause() {
      this._running = false;
      this._paused = true;

      this._trackCacheMap.forEach(function (track, key, map) {
        track.pause();
      });

      this.trigger(&quot;pause&quot;);
      return this;
    }
<span id='qrenderer-animation-AnimationProcess-method-resume'>    /**
</span>     * @method resume
     * 恢复动画
     */

  }, {
    key: &quot;resume&quot;,
    value: function resume() {
      this._running = true;
      this._paused = false;

      this._trackCacheMap.forEach(function (track, key, map) {
        track.resume();
      });

      this.trigger(&quot;resume&quot;);
      return this;
    }
<span id='qrenderer-animation-AnimationProcess-method-during'>    /**
</span>     * @method during
     * 添加动画每一帧的回调函数，方便链式调用。
     * @param  {Function} callback
     * @return {qrenderer.animation.AnimationProcess}
     */

  }, {
    key: &quot;during&quot;,
    value: function during(callback) {
      this.on(&quot;during&quot;, callback);
      return this;
    }
<span id='qrenderer-animation-AnimationProcess-method-done'>    /**
</span>     * @method done
     * 添加动画结束的回调，方便链式调用。
     * @param  {Function} callback
     * @return {qrenderer.animation.AnimationProcess}
     */

  }, {
    key: &quot;done&quot;,
    value: function done(callback) {
      this.on(&quot;done&quot;, callback);
      return this;
    }
<span id='qrenderer-animation-AnimationProcess-method-isFinished'>    /**
</span>     * @method isFinished
     * 判断整个动画过程是否已经完成，所有 Track 上的动画都完成则整个动画过程完成
     */

  }, {
    key: &quot;isFinished&quot;,
    value: function isFinished() {
      var isFinished = true;

      this._trackCacheMap.forEach(function (track, key, map) {
        if (!track.isFinished) {
          isFinished = false;
        }
      });

      return isFinished;
    }
<span id='qrenderer-animation-AnimationProcess-method-isPaused'>    /**
</span>     * @method isPaused
     * 是否暂停
     */

  }, {
    key: &quot;isPaused&quot;,
    value: function isPaused() {
      return !!this._paused;
    }
<span id='qrenderer-animation-AnimationProcess-method-delay'>    /**
</span>     * @method delay
     * 设置动画延迟开始的时间
     * @param  {Number} time 单位ms
     * @return {qrenderer.animation.AnimationProcess}
     */

  }, {
    key: &quot;delay&quot;,
    value: function delay(time) {
      this._delay = time;
      return this;
    }
  }]);

  return AnimationProcess;
}();

classUtil.mixin(AnimationProcess, Eventful);
var _default = AnimationProcess;
module.exports = _default;</pre>
</body>
</html>
